﻿using com.iot.core.boot;
using com.iot.core.data;
using com.iot.core.data.entity;
using com.iot.core.data.service;
using com.iot.core.exception;
using com.iot.core.infrastructure;
using com.iot.core.manager.id;
using com.iot.ht.Controllers.htuser.data;
using Icom.iot.core.ext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace com.iot.ht.Controllers.htuser.service
{
    public class HtUserService:BaseService<HtUser>,IHtUserService
    {
        readonly IRepository<HtUserDept> htUserDeptMapper; 
        readonly IHtUserRoleService htUserRoleService;
        public HtUserService(IRepository<HtUserDept> p1,
            IHtUserRoleService p2) 
        {
            htUserDeptMapper = p1;  
            htUserRoleService = p2;
        }
        public async Task< Page<HtUserDto> > PageAsync(HtUserQto qm)
        {             
            var DB = BaseMapper.DB;
            var q = htUserDeptMapper.GetAll()
                .Join(DB.Set<HtUser>(),
                    a => new { HtdeptId = a.HtdeptId, HtuserId = a.HtuserId, BDeleted = false },
                    b => new { HtdeptId = qm.HtdeptId, HtuserId = b.Id, BDeleted = b.Deleted },
                    (a, b) => new
                    {
                        Data = b,
                        State = a.State,
                        CrtDt = b.CrtDt,
                        HtdeptId = a.HtdeptId
                    }
                )
                .Join(DB.Set<HtDept>(),
                    a => new { HtdeptId = a.HtdeptId },
                    b => new { HtdeptId = b.Id },
                    (a, b) => new
                    {
                        Data = a.Data,
                        State = a.State,
                        CrtDt = a.CrtDt,
                        HtdeptId = a.HtdeptId,
                        HtdeptName = b.Name
                    }
                );
            if (qm.Id > 0)
            {
                q=q.Where(a => a.Data.Id==qm.Id);
            }
            else
            {
                if (!string.IsNullOrEmpty(qm.Key))
                {
                    q = q.Where(a => a.Data.Name.Contains(qm.Key)
                    || a.Data.Ename.Contains(qm.Key)
                    || a.Data.Mobile.Contains(qm.Key)
                    );
                }
                if (!string.IsNullOrEmpty(qm.State))
                {
                    q = q.Where(a => a.State == qm.State);
                }
            }
            var Total = await q.CountAsync();
            
            var r = new Page<HtUserDto>(Total, qm.Page, qm.PageSize);

            q = q.OrderByDescending(a => a.CrtDt);
            var l = await q.Skip((qm.Page - 1) * qm.PageSize).Take(qm.PageSize).ToListAsync();

            r.Records = new List<HtUserDto>();
            foreach (var m in l)
            {
                var mm = new HtUserDto();
                EntityToDto(m.Data, mm);
                mm.CrtDt = m.CrtDt;
                mm.State = m.State;
                mm.CrtDname = m.HtdeptName;
                mm.CrtDid = m.HtdeptId;
                r.Records.Add(mm);
            }
            var lids = r.Records.Select(a => a.Id).ToList();
            if (lids.Count > 0)
            {
                var lrole =await htUserRoleService.GetRolesAsync(lids, qm.HtdeptId);
                foreach(var mm in r.Records)
                {
                    var mr= lrole.Where(a=>a.Id1==mm.Id).FirstOrDefault();
                    if (mr != null)
                    {
                        mm.RoleList.Add(new IdNameDto
                        {
                            Id = mr.Id,
                            Name = mr.Name
                        }); 
                    }
                }
            }
            return r;
        }
        public async Task<HtUserDto> DetailAsync(HtUserDetailQto qm)
        {
            var qm2=new HtUserQto { Id= qm.Id, HtdeptId=qm.HtdeptId };
            var r = await PageAsync(qm2);
            return r.Records[0];
        }
        public HtUserDto InsertInit(BaseQto qm)
        {
            var mm = new HtUserDto();
            mm.Id = HtIdManager.Current.NextLong();
            mm.CrtDid = qm.Id;
            mm.CrtDname = BaseMapper.GetName(qm.Id, "Htdept");
            
            return mm;
        }


        public int Insert(HtUserDto mm)
        {
            var DB = BaseMapper.DB;
            var mold=BaseMapper.GetAll().Where(a=>a.Ename==mm.Ename).FirstOrDefault();
            if (mold != null)
            {
                throw new MyException("账号重复");
            }

            var m = new  HtUser();
            DtoToEntity(mm, m);
            m.Pwd = iot.core.manager.auth.AuthManager.Current.CreatePwd(mm.Ename, mm.Pwd);

            var mdept = new HtUserDept
            {
                Id = HtIdManager.Current.NextLong(),
                HtdeptId = mm.CrtDid,
                HtuserId = m.Id,
                State = "启用"
            };
            htUserDeptMapper.Insert(mdept, true );


            foreach (var mr in mm.RoleList)
            {
                var mrm = new HtUserRole
                {
                    Id = HtIdManager.Current.NextLong(),
                    HtroleId = mr.Id,
                    HtuserId = m.Id,
                    HtdeptId = m.CrtDid
                };
                htUserRoleService.Insert(mrm, true, false);
            }
            return Insert(m);
        }
        public int Update(HtUserDto mm)
        {
            var m = GetById(mm.Id);
            DtoToEntity(mm, m);

            if (mm.EditPwd)
            {
                m.Pwd = iot.core.manager.auth.AuthManager.Current.CreatePwd(mm.Ename, mm.Pwd);

            }
            var loldr = htUserRoleService.GetAll().Where(a => a.HtuserId == m.Id
                && a.HtdeptId == mm.CrtDid).ToList();
            foreach (var mr in mm.RoleList)
            {
                var mrm = loldr.Where(a => a.HtroleId == mr.Id).FirstOrDefault();
                if (mrm == null)
                {
                    mrm = new HtUserRole
                    {
                        Id = HtIdManager.Current.NextLong(),
                        HtroleId = mr.Id,
                        HtuserId = m.Id,
                        HtdeptId = m.CrtDid
                    };
                    htUserRoleService.Insert(mrm, true, false);
                }
            }

            var roleids = mm.RoleList.Select(a => a.Id).ToList();
            loldr.Where(a => !roleids.Contains(a.HtroleId))
                .ToList()
                .ForEach(mold =>
                {
                    htUserRoleService.Delete(mold, true, false);
                });
            return Update(m);
        }


        public int Qy(BaseQto mm)
        {
            var myContext = EngineContext.Current.Resolve<MyContext>();
            var su = myContext.Su;
            var m = htUserDeptMapper.GetAll()
                .Where(a => a.HtuserId == mm.Id && a.HtdeptId == su.CrtDid && !a.Deleted)
                .FirstOrDefault();
            m.State = "启用";
            htUserDeptMapper.Update(m,true);

            var muser = GetById(m.HtuserId);
            myContext.SetLogMemo($"启用用户:{muser.Name}");
            return htUserDeptMapper.SaveChagnes();

        }
        public int Ty(BaseQto mm)
        {
            var myContext = EngineContext.Current.Resolve<MyContext>();
            var su = myContext.Su;
            var m = htUserDeptMapper.GetAll()
                .Where(a => a.HtuserId == mm.Id && a.HtdeptId == su.CrtDid && !a.Deleted)
                .FirstOrDefault();
            m.State = "停用";
            htUserDeptMapper.Update(m, true);

            var muser = GetById(m.HtuserId);
            myContext.SetLogMemo($"停用用户:{muser.Name}");

            return htUserDeptMapper.SaveChagnes();
        }
    }
}
